/***************************************************************************
 创建者: 华磊
 开始时间: 2018.8.14
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2017.5.8 类的具体实现代码编写

 ***************************************************************************
 *  @file x.h
 *  功能:
 *
 *                                                                         *
 ***************************************************************************/
#ifndef CANBUSDEVICEDRIVER_H
#define CANBUSDEVICEDRIVER_H
#include <qvector.h>
//#define LONG64 int64_t
#include "gSoapFoundation/soapStub.h"
#include "MacroDefine/GeneralDefine.h"
#include <QQueue>
#include <QMutex>


enum E_NODE_MANAGE
{
    E_NODE_MANAGE_START_PDO=1,
    E_NODE_MANAGE_STOP_PDO=2,
    E_NODE_MANAGE_PREOP=0x80,
    E_NODE_MANAGE_RESET_NODE=0x81,
    E_NODE_MANAGE_RESET_COMMUNICATE=0x82
};

struct FrameData
{
    unsigned int frameId;
    QVector<unsigned char> data;
};

/**
 * @brief The CanbusDeviceDriver class can设备驱动类
 */
class CanbusDeviceDriver
{
public:
    CanbusDeviceDriver(QString canConfigFile);

public:
    int clearUserFrameBuffer();
    int receiveData_toUserBuffer1(int deviceId, int canbusId);
    int receiveData_toUserBuffer2(int deviceId, int canbusId);
    int receiveData_toBuffer(int deviceId, int canbusId,QQueue<FrameData> &bufferOut);
    int getPdoData_ch1(QVector<unsigned int> &nodeIdOut, QVector<unsigned int> &pdoIdOut,
                   QVector<QVector<unsigned char> > &dataListOut);
    int getPdoMasterData_ch1(QVector<unsigned int> &nodeIdOut, QVector<unsigned int> &pdoIdOut,
                   QVector<QVector<unsigned char> > &dataListOut);
    int getPdoData_ch2(QVector<unsigned int> &nodeIdOut, QVector<unsigned int> &pdoIdOut,
                   QVector<QVector<unsigned char> > &dataListOut);
    int getUserBuffer(QQueue<FrameData> &userFrameBuffersOut);
    int getUserBuffer(int busIdIn,QQueue<FrameData> &userFrameBuffersOut);

    int sendSyncFrame(int deviceId, int canbusId);
    int manageNode(int deviceId, int canbusId,unsigned int nodeId,E_NODE_MANAGE commandIn);

    int sendPdoData(int deviceId, int canbusId, unsigned int nodeId,unsigned int pdoId,
                    QVector<unsigned char> dataList);
    int sendPdoData_toMaster(int deviceId, int canbusId, unsigned int nodeId,unsigned int pdoId,
                    QVector<unsigned char> dataList);
    int sendNodeWatchDogFrame(int deviceId, int canbusId, unsigned int nodeId);
    int sendData(int deviceId, int canbusId, unsigned int frameId, QVector<unsigned char> dataList);
    int sendData_ext(int deviceId, int canbusId, unsigned int frameId, QVector<unsigned char> dataList);
    int sendData_remote(int deviceId, int canbusId, unsigned int frameId);
    int receiveData(int deviceId, int canbusId,QVector<unsigned int> &frameIdOut,
                    QVector<QVector<unsigned char> > &dataListReturn);
    int getReceiveNum(int deviceId, int canbusId);
    int closeDevice();
    bool isInitialOkStatus();

    int sdoUpload(int deviceIdIn, int canbusIdIn,int node
                  ,int rObIndex
                  ,int rObSubIndex
                  ,LONG64 &rData
                  ,int &rDataLen);
    int sdoDownload(int deviceIdIn, int canbusIdIn,int node
                    , int wObIndex
                    , int wObSubIndex
                    , LONG64 wData
                    , int wDataLen);//bug need todo .可能中间休息等待的时候接收的数据被一次pdo处理给清除了
    int sdoUpload_noCareFeedback(int deviceIdIn, int canbusIdIn, int node
                  , int rObIndex
                  , int rObSubIndex
                  );
    int sdoDownload_noCareFeedback(int deviceIdIn, int canbusIdIn,int node
                    , int wObIndex
                    , int wObSubIndex
                    , LONG64 wData
                    , int wDataLen);
    int sdoUpload_receive(int deviceIdIn, int canbusIdIn,int node
                          ,int rObIndex
                          ,int rObSubIndex
                          ,LONG64 &rData
                          ,int &rDataLen);


private:

    int getPdoData(int channelId, QVector<unsigned int> &nodeIdOut, QVector<unsigned int> &pdoIdOut,
                   QVector<QVector<unsigned char> > &dataListOut);
    int getPdoMasterData(int channelId, QVector<unsigned int> &nodeIdOut, QVector<unsigned int> &pdoIdOut,
                   QVector<QVector<unsigned char> > &dataListOut);
    int receiveUploadSdoDataResponse(int deviceIdIn, int canbusIdIn, int node, QVector<unsigned char> dataList,
                       int64_t &rData, int &rDataLen);
    int receiveDownloadSdoDataResponse(int deviceIdIn, int canbusIdIn, int node, QVector<unsigned char> dataList);


    void realTimeSleep(long long umicoroSecond);
    int initialDevice();

    void addMsg( int messageLevel,
                 std::string componentName,
                 std::string messageType,
                 int messageCode,
                 int robotId,
                 int parameter1 = 0,
                 int parameter2 = 0,
                 int parameter3 = 0,
                 int parameter4 = 0 );


private:
    QMutex mutex;
    bool isInitialOk;
    QQueue<FrameData> userFrameBuffers1;//
    QQueue<FrameData> userFrameBuffers2;//

};

#endif // CANBUSDEVICEDRIVER_H
